package com.ruoyi.back.v1.service

import cn.hutool.core.collection.ListUtil
import cn.hutool.core.date.DateUtil
import cn.hutool.core.util.StrUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.ruoyi.app.common.Data
import com.ruoyi.app.common.Ok
import com.ruoyi.app.common.PageData
import com.ruoyi.app.common.date
import com.ruoyi.back.mapper.*
import com.ruoyi.back.v1.domain.*
import com.ruoyi.common.core.page.TableSupport
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*


@Service
class FreezeTimeService {

    @Autowired
    private lateinit var freezeTimeMapper: FreezeTimeMapper

    fun notFreezeTime(id: Long): Date? =
        freezeTimeMapper.selectById(id)?.let {
            if (it.time != -1) {
                DateUtil.offsetDay(DateUtil.date(), it.time!!)
            } else {
                DateUtil.offsetMonth(DateUtil.date(), 120)
            }
        }

    fun initFreezeTime() {

        arrayListOf(
            FreezeTime().apply {
                time = 1
                timeDesc = "1天"
                orderNum = 0
            },
            FreezeTime().apply {
                time = 3
                timeDesc = "3天"
                orderNum = 1
            },
            FreezeTime().apply {
                time = 1
                timeDesc = "7天"
                orderNum = 2
            },
            FreezeTime().apply {
                time = 30
                timeDesc = "30天"
                orderNum = 3
            },
            FreezeTime().apply {
                time = 180
                timeDesc = "180天"
                orderNum = 4
            },
            FreezeTime().apply {
                time = 360
                timeDesc = "360天"
                orderNum = 5
            },
            FreezeTime().apply {
                time = -1
                timeDesc = "永久"
                orderNum = 6
            },
        ).forEach {
            freezeTimeMapper.insert(it)
        }
    }


    fun freezeTimeList(): Data<List<FreezeTime>> =
        Ok(
            "获取成功", freezeTimeMapper.selectList(
                KtQueryWrapper(FreezeTime::class.java)
                    .orderByAsc(FreezeTime::orderNum)
            )
        )
}


@Service
class FreeMemberTaskService {

    @Autowired
    private lateinit var freeMemberMapper: FreeMemberMapper

    fun saveFreeMemberTask(freeMember: FreeMember): Data<Boolean> =
        Ok("操作成功", run {
            freeMember.id?.run {
                freeMemberMapper.updateById(freeMember) > 0
            } ?: run {
                freeMemberMapper.insert(freeMember) > 0
            }
        })

    fun removeFreeMemberTask(ids: String): Data<Boolean> =
        Ok("操作成功", freeMemberMapper.deleteBatchIds(ids.split(",")) > 0)


    fun freeMemberTaskList() =
        Ok(
            "获取成功", freeMemberMapper.selectList(
                KtQueryWrapper(FreeMember::class.java)
                    .orderByDesc(FreeMember::createTime)
            )
        )
}

@Service
class PointUseDetailService {

    @Autowired
    private lateinit var pointUseDetailMapper: PointUseDetailMapper


    fun savePointUseDetail(pointUseDetail: PointUseDetail): Data<Boolean> =
        Ok("操作成功", run {
            pointUseDetail.id?.run {
                pointUseDetailMapper.updateById(pointUseDetail) > 0
            } ?: run {
                pointUseDetailMapper.insert(pointUseDetail) > 0
            }
        })


    fun getPointUseDetail() =
        Ok(
            "获取成功", pointUseDetailMapper.selectList(
                KtQueryWrapper(PointUseDetail::class.java)
            )
        )

}


@Service
class FreeMemberShareService {

    @Autowired
    private lateinit var freeMemberShareMapper: FreeMemberShareMapper

    fun saveFreeMemberShare(freeMemberShare: FreeMemberShare) =
        Ok("操作成功", run {
            freeMemberShare.id?.run {
                freeMemberShareMapper.updateById(freeMemberShare) > 0
            } ?: run {
                freeMemberShareMapper.insert(freeMemberShare) > 0
            }
        })

    fun getFreeMemberShare() =
        Ok(
            "获取成功", freeMemberShareMapper.selectOne(
                KtQueryWrapper(FreeMemberShare::class.java)
                    .last("limit 1")
            )
        )
}


@Service
class GlobalParamDetailService {

    @Autowired
    private lateinit var globalParamDetailMapper: GlobalParamDetailMapper


    fun saveGlobalParamDetail(globalParamDetail: GlobalParamDetail) =
        Ok("操作成功", run {
            globalParamDetail.id?.run {
                globalParamDetailMapper.updateById(globalParamDetail) > 0
            } ?: run {
                globalParamDetailMapper.insert(globalParamDetail) > 0
            }
        })

    fun globalParamDetail() = Ok(
        "获取成功", globalParamDetailMapper.selectOne(
            KtQueryWrapper(GlobalParamDetail::class.java)
                .last("limit 1")
        )
    )

    fun apiType(type: Int, videoDuration: Int?): Int {

        return globalParamDetailMapper.selectOne(
            KtQueryWrapper(GlobalParamDetail::class.java)
                .last("limit 1")
        )
            .run {
                when (type) {
                    //图片
                    1 -> picChangeFace ?: 1

                    //视频
                    else -> {

                        val api = videoChangeFace ?: 0
                        when (api) {
                            0 -> if ((videoDuration ?: 0) <= 60) 2 else 1
                            else -> api
                        }
                    }
                }
            }
    }
}

@Service
class ChangeFaceApiDetailService {

    @Autowired
    private lateinit var changeFaceApiDetailMapper: ChangeFaceApiDetailMapper

    data class Time(
        val year: Int,
        val month: Int,
        val day: Int
    )

    // 将秒转化为"时:分:秒"格式
    fun formatSecondsToHMS(seconds: Long): String {
        val remainingSeconds = seconds % 3600;
        val minutes = remainingSeconds / 60;
        val second = remainingSeconds % 60;

        return String.format("%02d分%02d秒", minutes, second);
    }


    fun List<ChangeFaceApiDetail>.trans(): List<ApiStatisticsVo> {


        val apiStatisticsVos = arrayListOf<ApiStatisticsVo>()
        apiStatisticsVos.add(ApiStatisticsVo().apply {
            date = "总计"
            picChangeFaceAliCount = count { it.changeFaceType == 1 && it.changeFaceApiType == 1 }
            picChangeFaceHuoshanCount = count { it.changeFaceType == 1 && it.changeFaceApiType == 2 }

            videoChangeFaceAliCount = count { it.changeFaceType == 2 && it.changeFaceApiType == 1 }
            videoChangeFaceHuoshanCount = count { it.changeFaceType == 2 && it.changeFaceApiType == 2 }

            videoChangeFaceAliDuration =
                formatSecondsToHMS(filter { it.changeFaceType == 2 && it.changeFaceApiType == 1 }
                    .sumOf { it.totalDuration ?: 0 })

            videoChangeFaceHuoshanDuration =
                formatSecondsToHMS(filter { it.changeFaceType == 2 && it.changeFaceApiType == 2 }
                    .sumOf { it.totalDuration ?: 0 })
        })

        map {
            it.apply {
                formatDate = DateUtil.format(it.createTime, "yyyy-MM-dd")
            }
        }.groupBy { it.formatDate }
            .forEach { (k, v) ->
                apiStatisticsVos.add(ApiStatisticsVo().apply {
                    date = k
                    picChangeFaceAliCount = v.count { it.changeFaceType == 1 && it.changeFaceApiType == 1 }
                    picChangeFaceHuoshanCount = v.count { it.changeFaceType == 1 && it.changeFaceApiType == 2 }

                    videoChangeFaceAliCount = v.count { it.changeFaceType == 2 && it.changeFaceApiType == 1 }
                    videoChangeFaceHuoshanCount = v.count { it.changeFaceType == 2 && it.changeFaceApiType == 2 }

                    videoChangeFaceAliDuration =
                        formatSecondsToHMS(v.filter { it.changeFaceType == 2 && it.changeFaceApiType == 1 }
                            .sumOf { it.totalDuration ?: 0 })

                    videoChangeFaceHuoshanDuration =
                        formatSecondsToHMS(v.filter { it.changeFaceType == 2 && it.changeFaceApiType == 2 }
                            .sumOf { it.totalDuration ?: 0 })
                })
            }

        return apiStatisticsVos
    }

    fun Date.time() = let { Time(DateUtil.year(it), DateUtil.month(it) + 1, DateUtil.dayOfMonth(it)) }

    fun apiTotalStatisticsVo(): Data<ApiTotalStatisticsVo> =
        Ok("获取成功", ApiTotalStatisticsVo().apply {
            picChangeFaceAliCount = changeFaceApiDetailMapper.selectCount(
                KtQueryWrapper(ChangeFaceApiDetail::class.java)
                    .eq(ChangeFaceApiDetail::changeFaceType, 1)
                    .eq(ChangeFaceApiDetail::changeFaceApiType, 1)
            )
            picChangeFaceHuoshanCount = changeFaceApiDetailMapper.selectCount(
                KtQueryWrapper(ChangeFaceApiDetail::class.java)
                    .eq(ChangeFaceApiDetail::changeFaceType, 1)
                    .eq(ChangeFaceApiDetail::changeFaceApiType, 2)
            )

            videoChangeFaceAliCount = changeFaceApiDetailMapper.selectCount(
                KtQueryWrapper(ChangeFaceApiDetail::class.java)
                    .eq(ChangeFaceApiDetail::changeFaceType, 2)
                    .eq(ChangeFaceApiDetail::changeFaceApiType, 1)
            )

            videoChangeFaceHuoshanCount = changeFaceApiDetailMapper.selectCount(
                KtQueryWrapper(ChangeFaceApiDetail::class.java)
                    .eq(ChangeFaceApiDetail::changeFaceType, 2)
                    .eq(ChangeFaceApiDetail::changeFaceApiType, 2)
            )
        })

    fun changeFaceApiDetailList(apiStatisticsDto: ApiStatisticsDto): PageData<ApiStatisticsVo> =
        (changeFaceApiDetailMapper.selectList(KtQueryWrapper(ChangeFaceApiDetail::class.java).apply {

            if (StrUtil.isNotBlank(apiStatisticsDto.beginDate) && StrUtil.isNotBlank(apiStatisticsDto.endDate)) {
                ge(ChangeFaceApiDetail::createTime, apiStatisticsDto.beginDate.date())
                le(ChangeFaceApiDetail::createTime, apiStatisticsDto.endDate.date())
            } else {
                when (apiStatisticsDto.type) {
                    1 -> {
                        DateUtil.date().time().let {
                            eq(ChangeFaceApiDetail::year, it.year)
                            eq(ChangeFaceApiDetail::month, it.month)
                            eq(ChangeFaceApiDetail::day, it.day)
                        }
                    }

                    2 -> {
                        DateUtil.offsetDay(DateUtil.date(), -1).time().let {
                            eq(ChangeFaceApiDetail::year, it.year)
                            eq(ChangeFaceApiDetail::month, it.month)
                            eq(ChangeFaceApiDetail::day, it.day)
                        }
                    }

                    3 -> {

                        DateUtil.date().let { dateTime ->

                            val offsetDay = DateUtil.offsetDay(dateTime, -7)
                            ge(ChangeFaceApiDetail::createTime, offsetDay)
                            le(ChangeFaceApiDetail::createTime, Date())
                                .orderByDesc(ChangeFaceApiDetail::createTime)
                        }
                    }

                    4 -> {
                        DateUtil.date().let { dateTime ->

                            val offsetDay = DateUtil.offsetDay(dateTime, -30)
                            ge(ChangeFaceApiDetail::createTime, offsetDay)
                            le(ChangeFaceApiDetail::createTime, Date())
                                .orderByDesc(ChangeFaceApiDetail::createTime)
                        }
                    }

                    else -> orderByDesc(ChangeFaceApiDetail::createTime)
                }
            }

        }).takeIf { it.isNotEmpty() }
            ?.run {
                trans()
            } ?: run {
            listOf(ApiStatisticsVo())
        }).let {

            TableSupport.buildPageRequest().let { pageDomain ->
                PageData<ApiStatisticsVo>().apply {
                    total = it.size.toLong()
                    rows = ListUtil.page(pageDomain.pageNum - 1, pageDomain.pageSize, it)
                }
            }
        }

}







